function varargout = TLCodeDlg(varargin)
% TL_MAIN_DLG manages user interface for TargetLink main block
%
% INPUT ARGUMENTS:
%   action     denotes an action string for dialog handling
%   Additional input arguments depend on action
% 
% OUTPUT ARGUMENTS
%   userData   dialog data, to be used from ds_generic_dlg
%
% AUTHOR
%   J.Knollann
%
% Copyright (c) 2002 by dSPACE GmbH, GERMANY

% $Author: Jens Knollmann (JensK) $
% $Revision: 1.14 $
% $Date: 2010/09/23 09:49:33MESZ $


% default input value
if isempty(varargin)
   varargin{1} = 'Create';
   varargin{2} = '';
end

% get action string
action = varargin{1};
if ~ischar(action),
   error('Invalid action string.');
end

% perform selected action
switch(lower(action)),
case 'getdatadescription',
   % return the block data description
   varargout{1} = i_GetDataDescription;
   if ds_error_check; return; end
case 'create',
   % create the dialog window
   ds_error_none;
   userData = i_Create; 
   if ds_error_check, return; end
   i_Update(userData);
   if ds_error_check, return; end
% case 'sync',
%    % synchronize data after user input
%    varargout{1} = i_Sync(varargin{2});
%    if ds_error_check; return; end
   
   %---------------------------------------
   % standard callbacks
   %---------------------------------------
   
case 'help',
   ds_error_none;
   varargout{1} = i_Help(varargin{2});
   if ds_error_check; return; end
   
   %---------------------------------------
   % custom callbacks
   %---------------------------------------
   
case 'update',   
   varargout{1} = i_Update(varargin{2});
case 'remove',   
   varargout{1} = i_Remove(varargin{2});
case 'comment',  
   varargout{1} = i_Comment(varargin{2});
case 'rename',  
   varargout{1} = i_Rename(varargin{2});
case  'report',
   varargout{1} = i_Report(varargin{2});
case 'overview',
   varargout{1} = i_Overview(varargin{2});
   
otherwise
   error('Invalid action string.');
   return; %#ok
end


%-------------------------------------------------------------------------------
% private function getting dSDD Simulation Data
%-------------------------------------------------------------------------------

function dSDDData = i_Get_dSDD_Data()

dSDDData.ApplicationName = dsdd_manage_application('GetApplication');
dSDDData.Sim.Name = dsdd('GetChildrenNames', ['//DD0/' dSDDData.ApplicationName '/Experiment/CoverageTest']);


%-------------------------------------------------------------------------------
% private function returning block data description
%-------------------------------------------------------------------------------

function dataDescription = i_GetDataDescription()

% callback actions
dataDescription.callBackActions = { ...
      'getdatadescription', ...
      ... % 'sync',        ...
      ...
      ... % 'XMLStyleSheetBrowse', ...
      'Update',      ...
      'Rename',      ...
      'Comment',     ...
      'Remove',      ...
      'Report',      ...
      'Overview'   ...
   };

% property names
dataDescription.propertyNames = { ...
      'revisionNumber', ...
      ... % 'XMLStyleSheet', ...
   };

% Get the current dSDD simulation data
dSDDData = i_Get_dSDD_Data;
if ds_error_check; return; end 

% revisionNumber
dataDescription.revisionNumber.dataType     = 'integer';
dataDescription.revisionNumber.validValues  = 1;
dataDescription.revisionNumber.defaultValue = 1;
dataDescription.revisionNumber.attributes   = {'read-only','hidden'};

% Application
dataDescription.Application.dataType        = 'string';
dataDescription.Application.validValues     = dSDDData.ApplicationName;
dataDescription.Application.defaultValue    = dSDDData.ApplicationName;
dataDescription.Application.attributes      = {'never-save'};

% ReportRange
dataDescription.ReportRange.dataType        = 'string array';
dataDescription.ReportRange.validValues     = {'all' dSDDData.Sim(1).Name{:}};
dataDescription.ReportRange.defaultValue    = {'all'};
dataDescription.ReportRange.attributes      = {'never-save'};


%-------------------------------------------------------------------------------
% private function creating the dialog
%-------------------------------------------------------------------------------

function userData = i_Create

% This dialog cannot be opened in stand-alone mode
if strcmp(tl_get_blockset_mode, 'stand-alone')
    ds_error_msg('The TargetLink Code Coverage Dialog is not available in stand-alone mode.', ...
                 'Title','Dialog can not be opened');
             userData = [];
    return;
end

dataDescription = i_GetDataDescription;

buttonWidth = 70;

pushButtonRename = { ...
      'Tag','Rename', ...
      'Style', 'pushbutton', ...
      ...'SetPosition',    'll = GetPoint(''Update'',''ul'') + 2 * rowDelta;', ...
      'UiControlWidth', buttonWidth, ...
      'LabelStrings',   'Rename' ...
      ... % 'ToolTipString',  sprintf(['']) ...
   };
pushButtonComment = { ...
      'Tag','Comment', ...
      'Style', 'pushbutton', ...
      'SetPosition',    'll = GetPoint(''Rename'',''ul'') + 2 * rowDelta;', ...
      'UiControlWidth', buttonWidth, ...
      'LabelStrings',   'Comment' ...
      ... % 'ToolTipString',  sprintf(['']) ...
   };
pushButtonRemove = { ...
      'Tag','Remove', ...
      'Style', 'pushbutton', ...
      'SetPosition',    'll = GetPoint(''Comment'',''ul'') + 2 * rowDelta;', ...
      'UiControlWidth', buttonWidth, ...
      'LabelStrings',   'Remove' ...
      ... % 'ToolTipString',  sprintf(['']) ...
   };
pushButtonUpdate = { ...
      'Tag','Update', ...
      'Style', 'pushbutton', ...
      'SetPosition',    'll = GetPoint(''Remove'',''ul'') + 2 * rowDelta;', ...
      'UiControlWidth', buttonWidth, ...
      'LabelStrings',   'Update' ...
      ... % 'ToolTipString',  sprintf(['']) ...
   };
listBoxReportRange = { ...
      'Tag','ReportRange', ...
      'Style', 'includeExcludeListbox', ...
      'Headline',        {'Coverage data','Include in report'}, ...
      'UiControlSize', [250 115], ...
      'SetPosition',    'ul = GetPoint(''Update'',''ur'') + 4 * colDelta;' ...
      'AssociatedButton',{'>>','<<'}, ...
      'KeepSelectedItems','on',...
      ... % 'ToolTipString',  sprintf(['']) ...
   };

pushButtonReport = { ...
      'Tag','Report', ...
      'Style', 'pushbutton', ...
      'SetPosition',    'ul = GetPoint(''ReportRange'',''ur'') + 4 * colDelta;', ...
      'UiControlWidth', buttonWidth, ...
      'LabelStrings',    'Report' ...
      ... % 'ToolTipString',  sprintf(['']) ...
   };
pushButtonOverview = { ...
      'Tag','Overview', ...
      'Style', 'pushbutton', ...
      'SetPosition',    'ul = GetPoint(''Report'',''ll'') - 2 * rowDelta;', ...
      'UiControlWidth', buttonWidth, ...
      'LabelStrings',   'Overview' ...
      ... % 'ToolTipString',  sprintf(['']) ...
   };

userData = ds_generic_dlg('Create', ...
   'FigureTag',         '#Fig_tl_c_cov_dlg', ...
   'Title',             'Code Coverage Report', ...
   'DataDescription',   dataDescription, ...
   'FigureWidth',       500, ...
   'CallbackFcn',       mfilename, ...
   ...
   pushButtonOverview{:}, ...
   pushButtonReport{:},   ...
   listBoxReportRange{:}, ...
   pushButtonUpdate{:},   ...
   pushButtonRemove{:},   ...
   pushButtonComment{:},  ...
   pushButtonRename{:},   ...
   'standardButtons', 'off' ...
   );


%-------------------------------------------------------------------------------
% private function to synchronize data after user input
%-------------------------------------------------------------------------------

% function userData = i_Sync(userData)
% % sync procedure depends on which uicontrol has been changed
% currentUiControl = userData.currentUiControl;
% % if the dialog is just created or page has changed
% if currentUiControl == 0,
%    userData.bApplyUiControls = 1;
%    userData.bApplyData       = 0;
%    userData.bClose           = 0;
%    return
% end
% 
% % Get the current dSDD simulation data
% dSDDData = i_Get_dSDD_Data;
% 
% % switch between different synchronizing procedures
% switch userData.uiControl(currentUiControl).tag
% case 'Application',
%    inputStr = userData.uiControl(currentUiControl).value;
%    tmp = find(strcmp(inputStr, userData.uiControl(currentUiControl).dataStrings));
%    idx = userData.dataDescription.ReportRange.uiControl;
%    userData.uiControl(idx).dataStrings = ...
%       dSDDData.SubsystemRef(tmp).SimulationID;
%    userData.uiControl(idx).value      = 'all';
% end
% 
% userData.bApplyUiControls = 1;
% userData.bApplyData       = 1;
% userData.bClose           = 0;

%-------------------------------------------------------------------------------
% private function to manage the Update button
%-------------------------------------------------------------------------------
function userData = i_Update(userData)

% Get the current dSDD simulation data
dSDDData = i_Get_dSDD_Data;

% ReportRange
idx = userData.dataDescription.ReportRange.uiControl;
userData.uiControl(idx).dataStrings = {'all' dSDDData.Sim(1).Name{:}};
tmp = find(~ismember(userData.uiControl(idx).value,userData.uiControl(idx).dataStrings));
if ~isempty(tmp),
   userData.uiControl(idx).value(tmp) = [];
end

if isempty(userData.uiControl(idx).value),
   userData.uiControl(idx).value = {'all'};
end

userData.bApplyUiControls = 1;
userData.bApplyData       = 0;
userData.bClose           = 0;

userData = ds_generic_dlg('Update', userData);
set(userData.hDlg, 'UserData', userData);

%-------------------------------------------------------------------------------
% private function to manage the Remove button
%-------------------------------------------------------------------------------
function userData = i_Remove(userData)
idxReportRange = userData.dataDescription.ReportRange.uiControl;
currElement = userData.uiControl(idxReportRange).currElement;

% Get the current dSDD simulation data
dSDDData = i_Get_dSDD_Data;

for i = length(currElement) : -1 : 1,
   if length(userData.uiControl(idxReportRange).dataStrings) < currElement(i)
      currElement(i) = length(userData.uiControl(idxReportRange).dataStrings);
      if ~strcmp(userData.uiControl(idxReportRange).dataStrings{currElement(i)},'all')
         dsdd('Delete', ...
            ['//DD0/' dSDDData.ApplicationName '/Experiment/CoverageTest/' ...
            userData.uiControl(idxReportRange).dataStrings{currElement(i)}]);
         userData.uiControl(idxReportRange).currElement = currElement(i)-1;
      end
      break;
   else
      if ~strcmp(userData.uiControl(idxReportRange).dataStrings{currElement(i)},'all'),
         dsdd('Delete', ...
            ['//DD0/' dSDDData.ApplicationName '/Experiment/CoverageTest/' ...
               userData.uiControl(idxReportRange).dataStrings{currElement(i)}]);
      end
   end
end
userData = i_Update(userData);

%-------------------------------------------------------------------------------
% private function to manage the Comment button
%-------------------------------------------------------------------------------
function userData = i_Comment(userData)

% Get the current dSDD simulation data
dSDDData = i_Get_dSDD_Data;

idxReportRange = userData.dataDescription.ReportRange.uiControl;
currElement = userData.uiControl(idxReportRange).currElement;
for i = length(currElement) : -1 :1,
   if length(userData.uiControl.dataStrings) < currElement(i),
      currElement(i) = length(userData.uiControl.dataStrings);
   end
   if ~strcmp(userData.uiControl.dataStrings{currElement(i)},'all'),
      description = dsdd('Get', ...
         ['//DD0/' dSDDData.ApplicationName '/Experiment/CoverageTest/' ...
            userData.uiControl(idxReportRange).dataStrings{currElement(i)}], ...
         'Description');
      if isempty(description),
         description = '';
      end
      description = inputdlg('Please type in the new Comment:',['Change Comment for Simulation: ' userData.uiControl(idxReportRange).dataStrings{currElement(i)}],10,{description});
      if ~isempty(description),
         textSize = size(description{1});
         comment = [];
         for j = 1:textSize(1),
            comment = [comment deblank(description{1,1}(j,1:end)) char(10)];
         end
         comment = deblank(comment);
         dsdd('Set', ['//DD0/' dSDDData.ApplicationName '/Experiment/CoverageTest/' ...
               userData.uiControl(idxReportRange).dataStrings{currElement(i)}], ...
            'Description', comment);
      end
   end
end

userData.bApplyUiControls = 0;
userData.bApplyData       = 0;
userData.bClose           = 0;

%-------------------------------------------------------------------------------
% private function to manage the Rename button
%-------------------------------------------------------------------------------
function userData = i_Rename(userData)
simNameOld = '';
simNameNew = '';

% Get the current dSDD simulation data
dSDDData = i_Get_dSDD_Data;

idx = userData.dataDescription.ReportRange.uiControl;
currElement = userData.uiControl(idx).currElement;
for i = length(currElement) : -1 :1,
   if length(userData.uiControl.dataStrings) < currElement(i),
      currElement(i) = length(userData.uiControl.dataStrings);
   end
   if ~strcmp(userData.uiControl.dataStrings{currElement(i)},'all'),
      simNameOld = userData.uiControl(idx).dataStrings{currElement(i)};
      simNameNew = inputdlg('Please type in the new name:','Change Name',1,{simNameOld});
      if isempty(simNameNew),
         continue
      end
      simNameNew = deblank(simNameNew{1,1});
      if strcmpi(simNameNew,'all')
         ds_error_msg('Using the simulation name ''all'' is prohibited. ');
      else
         errorCode = dsdd('SetAttribute', ...
            ['//DD0/' dSDDData.ApplicationName '/Experiment/CoverageTest/' ...
               userData.uiControl(idx).dataStrings{currElement(i)}], ...
            'name', simNameNew);
         if errorCode > 0
            dSDDData = i_Get_dSDD_Data;
            simNameNew = dSDDData.Sim(1).Name{currElement(i) - 1};
         end
      end
         userData.uiControl(idx).dataStrings{currElement(i)} = simNameNew;
   end
end
tmp = find(strcmp(simNameOld, userData.uiControl(idx).value));
if ~isempty(tmp) && ~isempty(simNameNew)
   userData.uiControl(idx).value{tmp} = simNameNew;
end

userData.bApplyUiControls = 1;
userData.bApplyData       = 0;
userData.bClose           = 0;
userData = i_Update(userData);

%-------------------------------------------------------------------------------
% private function to manage the Overview button
%-------------------------------------------------------------------------------
function userData = i_Overview(userData)
idx = userData.dataDescription.ReportRange.uiControl;
if ismember('all', userData.uiControl(idx).value),
   tl_code_coverage('Overview');   
else
   tl_code_coverage('Overview', userData.uiControl(idx).value);
end

userData.bApplyUiControls = 0;
userData.bApplyData       = 0;
userData.bClose           = 0;

%-------------------------------------------------------------------------------
% private function to manage the Report button
%-------------------------------------------------------------------------------
function userData = i_Report(userData)
idx = userData.dataDescription.ReportRange.uiControl;
if ismember('all', userData.uiControl(idx).value),
   tl_code_coverage('Report');
else
   tl_code_coverage('Report', userData.uiControl(idx).value);
end

userData.bApplyUiControls = 0;
userData.bApplyData       = 0;
userData.bClose           = 0;
